﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using System.Security.Cryptography;
using System.Text;
using Lasalara.Model;
using RestSharp;

namespace Lasalara.ViewModel
{
    public class UserViewModel : GlobalViewModel
    {
        #region webRequests

        /// <summary>
        /// Check if the user exists in the webserver
        /// </summary>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        /// <param name="callback">Callback method</param>
        public void GetUserLoginWebRequest(string email, string password, Action<RestResponse, string, string> callback)
        {
            var client = new RestClient(App.BaseUrl);
            var request = new RestRequest(Method.POST)
                              {
                                  Resource = "signin",
                                  RequestFormat = DataFormat.Json
                              };
            request.AddParameter("em", email);
            request.AddParameter("pw", password);
            client.ExecuteAsync(request, (response) => callback(response as RestResponse, email, password));
        }

        /// <summary>
        /// Sends users password to supplied email
        /// </summary>
        /// <param name="email">Users email</param>
        /// <param name="callback">Callback method</param>
        public void SendUserPasswordWebRequest(string email, Action<RestResponse, string> callback)
        {
            var client = new RestClient(App.BaseUrl);
            var request = new RestRequest(Method.POST)
                              {
                                  Resource = "email",
                              };
            request.AddParameter("em", email);
            client.ExecuteAsync(request, (response) => callback(response as RestResponse, email));
        }

        /// <summary>
        /// Signs the user up
        /// </summary>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        /// <param name="callback">Callback method</param>
        public void SignUpWebRequest(string email, string password, Action<RestResponse, string, string> callback)
        {
            var client = new RestClient(App.BaseUrl);
            var request = new RestRequest(Method.POST)
                              {
                                  Resource = "signup",
                              };
            request.AddParameter("em", email);
            request.AddParameter("pw", password);
            client.ExecuteAsync(request, (response) => callback(response as RestResponse, email, password));
        }

        #endregion

        /// <summary>
        /// Creates new user or refreshes password of old user and saves it to localstorage file
        /// </summary>
        /// <param name="data">The Dictionary containing the values 
        /// (uk = user key, books = list of titles and keys, err = error exception)</param>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        public void CreateOrLoginCurrentUser(Dictionary<string, string> data, string email, string password)
        {
            var books = BookViewModel.GetBooksFromDictionary(data);
            // If user exists but has a different password change the password of that user.
            var existingUser = GetAppSettings(email) as User;
            if (existingUser != null)
            {
                existingUser.Password = EncryptData(password);
                SaveUser(existingUser);
            }
            else
            {
                if (books == null)
                {
                    ShowToast(AppResources.Error, AppResources.ErrorLoggingIn);
                    return;
                }
                var userKey = data["uk"];
                var user = new User(email, userKey, books, new List<Book>(), true, EncryptData(password));
                SaveUser(user);
            }
            
            SetAppSetting("currentUser", email);
        }

        /// <summary>
        /// Creates new user and saves it to localstorage file
        /// </summary>
        /// <param name="data">users key</param>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        public void CreateCurrentUser(string data, string email, string password)
        {
            var user = new User(email, data, new List<Book>(), new List<Book>(), true,
                                EncryptData(password));
            SaveUser(user);
            SetAppSetting("currentUser", email);
        }

        /// <summary>
        /// Validate if the user exists
        /// </summary>
        /// <param name="data">The Dictionary containing the values 
        /// (uk = user key, books = list of titles and keys, err = error exception)</param>
        public static bool ValidateLogin(Dictionary<string, string> data)
        {
            if (data != null)
            {
                // Some error
                if (data.ContainsKey("err"))
                {
                    // Invalid username or password
                    if (data["err"] == "0")
                    {
                        ShowToast(AppResources.Error, AppResources.WrongUserOrPassword);
                        return false;
                    }
                    ShowToast(AppResources.Error, AppResources.ErrorLoggingIn);
                    return false;
                }
                // User was found
                return true;
            }
            ShowToast(AppResources.Error, AppResources.ErrorLoggingIn);
            return false;
        }

        /// <summary>
        /// Validate if the user can be created
        /// </summary>
        /// <param name="response">The response from webRequest</param>
        public bool ValidateLogin(string response)
        {
            // Some error
            if (!string.IsNullOrEmpty(response))
            {
                // Email taken
                if (response == "0")
                {
                    ShowToast(AppResources.Error, AppResources.EmailInUse);
                    return false;
                }
                if (response.StartsWith(String.Format("{0}", "''")))
                {
                    ShowToast(AppResources.Error, AppResources.ErrorRegistering);
                    return false;
                }
                return true;
            }
            ShowToast(AppResources.Error, AppResources.ErrorRegistering);
            return false;
        }


        /// <summary>
        /// Check if user email and password have already been saved to the phone
        /// </summary>
        /// <param name="email">The email to check</param>
        /// <param name="password">The password to check</param>
        public static bool CheckIfLocalUserExists(string email, string password)
        {
            var user = GetAppSettings(email) as User;
            if (user != null)
            {
                var encodedPassword = user.Password;
                var unProtectedPassword = ProtectedData.Unprotect(encodedPassword, null);
                var decodedPassword = Encoding.UTF8.GetString(unProtectedPassword, 0, unProtectedPassword.Length);

                if (email.Equals(user.Email) && password.Equals(decodedPassword))
                {
                    return true;
                }
            }
            return false;
        }


        /// <summary>
        /// Check if user is logged in from IsolatedStorageSettigns
        /// </summary>
        public static bool IsUserLoggedIn()
        {
            var result = GetAppSettings("loggedIn");
            if (result != null)
            {
                return (bool) result;
            }
            return false;
        }
    }
}